﻿#include "Spaceship.h"

struct Vertex
{
	float x, y, z;
	DWORD color;
	float tu, tv;
	static CONST DWORD FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1;
};

// 无纹理
struct Vertex2
{
	float x, y, z;
	DWORD color;
	static CONST DWORD FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
};

Spaceship::Spaceship(Graphics& graphics, int width, int height)
{
	HRESULT hresult;
	_Timer.SetTime(30);
	_Timer.Start();

	D3DXMATRIX _ortho;
	// 设置正交投影
	D3DXMatrixOrthoLH(&_ortho, width, height, 0.1f, 1000.0f);
	GetDevice(graphics)->SetTransform(D3DTS_PROJECTION, &_ortho);
	// 关闭光照
	GetDevice(graphics)->SetRenderState(D3DRS_LIGHTING, FALSE);
	// 渲染模式不进行剔除
	GetDevice(graphics)->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

	DWORD color = D3DCOLOR_XRGB(255, 255, 255);
	Vertex data[] =
	{
		{ 0.f, 0.f, 0.1f, color, 0, 1},
		{ 117.f, 0.f, 0.1f, color, 1, 1},
		{ 117.f,  120.f, 0.1f, color, 1, 0},

		{ 117.f, 120.f, 0.1f, color, 1, 0},
		{ 0.f,  120.f, 0.1f, color, 0, 0},
		{ 0.f, 0.f, 0.1f, color, 0, 1}
	};
	
	hresult = GetDevice(graphics)->CreateVertexBuffer(
		sizeof(data),
		0,
		Vertex::FVF,
		D3DPOOL_DEFAULT,
		&_VertexBuffer,
		nullptr
	);
	if (FAILED(hresult))
		HWND_EXCEPT();
	void* ptr;
	hresult = _VertexBuffer->Lock(0, sizeof(data), (void**)&ptr, 0);
	if (FAILED(hresult))
		HWND_EXCEPT();
	memcpy(ptr, data, sizeof(data));
	_VertexBuffer->Unlock();

	hresult = D3DXCreateTextureFromFile(GetDevice(graphics), "images/hero3.png", &_Texture);
	if (hresult != D3D_OK)
		HWND_EXCEPT();
	
	Vertex2 data2[] =
	{
		{-320.f, 0.f, 0.1f, color},
		{320.f, 0.f, 0.1f, color},

		{0.f, 240.f, 0.1f, color},
		{0.f, -240.f, 0.1f, color},
	};
	hresult = GetDevice(graphics)->CreateVertexBuffer(
		sizeof(data2),
		0,
		Vertex2::FVF,
		D3DPOOL_DEFAULT,
		&_Line,
		nullptr
	);
	if (FAILED(hresult))
		HWND_EXCEPT();

	hresult = _Line->Lock(0, sizeof(data2), (void**)&ptr, 0);
	if (FAILED(hresult))
		HWND_EXCEPT();
	memcpy(ptr, data2, sizeof(data2));
	_Line->Unlock();

	_x = _y = _z = 0.0f;
	_run = false;
	_GameDir = GameDir::left;
}

Spaceship::~Spaceship()
{

}

void Spaceship::Keydown()
{
	if (GetAsyncKeyState('A') & 0x8000)
	{
		_run = true;
		_GameDir = GameDir::left;
	}
	else if (GetAsyncKeyState('W') & 0x8000)
	{
		_run = true;
		_GameDir = GameDir::up;
	}
	else if (GetAsyncKeyState('D') & 0x8000)
	{
		_run = true;
		_GameDir = GameDir::right;
	}
	else if (GetAsyncKeyState('S') & 0x8000)
	{
		_run = true;
		_GameDir = GameDir::down;
	}
	else 
	{
		_run = false;
	}
}

void Spaceship::Run(float ti)
{
	if (_run) 
	{
		switch (_GameDir)
		{
		case GameDir::left:
			_x -= 1 * ti;
			break;
		case GameDir::up:
			_y += 1 * ti;
			break;
		case GameDir::right:
			_x += 1 * ti;
			break;
		case GameDir::down:
			_y -= 1 * ti;
			break;
		default:
			break;
		}
	}
}

void Spaceship::Draw(Graphics& graphics)
{
	// 为纹理图像设置alpha透明度。
	GetDevice(graphics)->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
	GetDevice(graphics)->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	GetDevice(graphics)->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

	D3DXMATRIX matRotation;
	float angle = D3DX_PI / 2;
	D3DXMatrixRotationZ(&matRotation, 0.0f);
	D3DXMATRIX matTransform;
	D3DXMatrixTranslation(&matTransform, _x, _y, _z);
	D3DXMATRIX matWolrd = matRotation * matTransform;
	GetDevice(graphics)->SetTransform(D3DTS_WORLD, &matWolrd);
	// 设置纹理
	GetDevice(graphics)->SetTexture(0, _Texture.Get());
	// 设置顶点
	GetDevice(graphics)->SetStreamSource(0, _VertexBuffer.Get(), 0, sizeof(Vertex));
	GetDevice(graphics)->SetFVF(Vertex::FVF);
	GetDevice(graphics)->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

	// 关闭alpha。
	GetDevice(graphics)->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
}

void Spaceship::Coordinate(Graphics& graphics)
{
	D3DXMATRIX matRotation;
	float angle = D3DX_PI / 2;
	D3DXMatrixRotationZ(&matRotation, 0.0f);
	D3DXMATRIX matTransform;
	D3DXMatrixTranslation(&matTransform, 0.f, 0.f, 0.f);
	D3DXMATRIX matWolrd = matRotation * matTransform;
	GetDevice(graphics)->SetTransform(D3DTS_WORLD, &matWolrd);
	// 绘制坐标直线
	GetDevice(graphics)->SetStreamSource(0, _Line.Get(), 0, sizeof(Vertex2));
	GetDevice(graphics)->SetFVF(Vertex2::FVF);
	GetDevice(graphics)->DrawPrimitive(D3DPT_LINELIST, 0, 2);
}
